#pragma once

#include <unordered_map>
#include <vector>
#include "Base.h"
#include "jsontable/table_interface.h"

class ITableCache
{
public:
	ITableCache() {}
	virtual ~ITableCache() {}

	virtual bool LoadData() = 0;
	virtual ITableCache* New() const = 0;
	virtual std::string_view Name() const = 0;
};

template <typename T>
class CTableCache : public ITableCache
{
public:
	CTableCache() {}
	virtual ~CTableCache() {}

	virtual std::string_view Name() const {
		return GetTableName<T>();
	}

	const T* GetEntry(uint32 iIdx) const {
		if (m_hasIndex) {
			auto itr = m_mapTable.find(iIdx);
			return itr != m_mapTable.end() ? &itr->second : NULL;
		} else {
			return iIdx < m_table.size() ? &m_table[iIdx] : NULL;
		}
	}

	size_t GetNumRows() const {
		if (m_hasIndex) {
			return m_mapTable.size();
		} else {
			return m_table.size();
		}
	}

	typedef typename std::unordered_map<uint32, T>::const_iterator Iterator;
	Iterator Begin() const { return m_mapTable.begin(); }
	Iterator End() const { return m_mapTable.end(); }

	typedef typename std::vector<T>::const_iterator VIterator;
	VIterator VBegin() const { return m_table.begin(); }
	VIterator VEnd() const { return m_table.end(); }

protected:
	std::vector<T> m_table;
	std::unordered_map<uint32, T> m_mapTable;
	static const bool m_hasIndex;
};

template <typename T>
const bool CTableCache<T>::m_hasIndex = GetTableKeyName<T>()[0] != '\0';
